package com.tensai.study.framework.reactornetty.demo;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import lombok.extern.slf4j.Slf4j;
import reactor.netty.Connection;
import reactor.netty.tcp.TcpServer;

import java.security.cert.CertificateException;
import java.time.Duration;
import java.util.List;

@Slf4j
public class MyTcpServer {

  public static void main(String[] args) throws CertificateException, InterruptedException {
    SelfSignedCertificate cert = new SelfSignedCertificate();
    SslContextBuilder sslContextBuilder =
        SslContextBuilder.forServer(cert.certificate(), cert.privateKey());

    TcpServer.create()   // 准备要配置的TCP服务器。
             // 配置端口号
             .port(1551)
             // 使用自签名证书。
             .secure(spec -> spec.sslContext(sslContextBuilder))
        //.wiretap()
        .doOnConnection(MyTcpServer::onConnect)
        .bindUntilJavaShutdown(Duration.ofSeconds(30), null);
    // 以阻塞方式启动服务器，并等待其完成初始化。
  }

  private static void onConnect(Connection conn) {
    // 将处理程序添加到netty管道
    conn.addHandler(new StringToIntegerDecoder());
    MyServerConnection myConn = new MyServerConnection(conn);
    log.info("New client connected: {}", conn);
    myConn.handle();
  }

  /**
   * 返回接收字节数的解码器。
   */
  public static class StringToIntegerDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
      int n = in.readableBytes();
      if (in.readableBytes() > 0) {
        in.readBytes(n);
        out.add(n); // 将解码器的结果存储在此处
      }
    }
  }
}
